package com.ruoyi.system.listener;

import com.ruoyi.common.modbus.data.MiiHmDeviceData;
import com.ruoyi.common.modbus.message.MiiMessage;
import com.ruoyi.common.modbus.utils.CacheObjectUtils;
import com.ruoyi.common.modbus.utils.CacheShebeiUtils;
import com.ruoyi.system.config.IotModbusServerConfig;
import com.ruoyi.system.domain.IotGateway;
import com.ruoyi.system.domain.IotVariable;
import com.ruoyi.system.domain.IotVariableValue;
import com.ruoyi.system.domain.IotVariableValueTemp;
import com.ruoyi.system.domain.vo.IotDeviceVo;
import com.ruoyi.system.domain.vo.IotEdgeEndVo;
import com.ruoyi.system.domain.vo.IotManageEndVo;
import com.ruoyi.system.domain.vo.IotVariableVo;
import com.ruoyi.system.mapper.*;
import com.takeoff.iot.modbus.netty.channel.MiiChannel;
import com.takeoff.iot.modbus.netty.listener.MiiListener;
import com.takeoff.iot.modbus.netty.message.MiiInMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class IotDataListener implements MiiListener {


    private final int dataLength = 8;

    @Autowired
    private IotDeviceMapper iotDeviceMapper;

    @Autowired
    private IotVariableMapper iotVariableMapper;

    @Autowired
    private IotManageEndMapper iotManageEndMapper;

    @Autowired
    private IotEdgeEndMapper iotEdgeEndMapper;

    @Autowired
    private IotVariableValueMapper iotVariableValueMapper;

    @Autowired
    private IotModbusServerConfig iotModbusServerConfig;

    @Autowired
    private IotVariableValueTempMapper iotVariableValueTempMapper;

    /**
     * 010314 00000000 4246675e 00000000 00000000 00000000 65bd
     * 第一个数据是阀门开关状态，第二个为电池容量，第三个为实时压力，第四个为实时流量，第五个为累计流量
     *
     * @param channel 消息通道
     * @param message 接收到的设备信息
     */
    @Override
    public synchronized  void receive(MiiChannel channel, MiiMessage message) {
        MiiHmDeviceData data = (MiiHmDeviceData) message.data();
        log.info("采集数据接受处理数据：" + channel +"------------"+channel.name() + message.deviceGroup() + data.data());
        String sn = CacheShebeiUtils.get(message.deviceGroup());
//        String sn = CacheObjectUtils.get(channel);
        log.info("从机地址：" + message.slaveAddress() + "  SN：" + sn);
        // 需要加判断是区别透传还是获取数据
        IotManageEndVo iotGatewayManage = iotManageEndMapper.selectGatewayBySn(sn);

        IotEdgeEndVo iotGatewayEdge = iotEdgeEndMapper.selectGatewayBySn(sn);

        if (iotGatewayManage == null && iotGatewayEdge == null) {
            analysisData(channel, message, sn);
        }

        if (iotGatewayManage == null && iotGatewayEdge != null) {
            // 边缘端给管理端发送消息
            // 查询管理端网关
            List<IotGateway> iotGatewayManageList = iotManageEndMapper.selectGatewayByPassthrough(iotGatewayEdge.getPassthroughId());
            for (IotGateway iotGateway : iotGatewayManageList) {
                log.info("透传边缘端发消息给管理端：SN：" + iotGateway.getSn());
                iotModbusServerConfig.getMiiServer().sender().passThrough(iotGateway.getSn(), message.toBytes());
            }
        }

        if (iotGatewayManage != null && iotGatewayEdge == null) {
            // 管理端给边缘端发送消息
            List<IotGateway> iotGatewayEdgeList = iotEdgeEndMapper.selectGatewayByPassthrough(iotGatewayManage.getPassthroughId());
            for (IotGateway iotGateway : iotGatewayEdgeList) {
                log.info("透传管理端发消息给边缘端：SN：" + iotGateway.getSn());
                iotModbusServerConfig.getMiiServer().sender().passThrough(iotGateway.getSn(), message.toBytes());
            }
        }

    }

    private void analysisData(MiiChannel channel, MiiMessage message, String sn) {
        log.info("解析数据sn=" + sn);
        MiiHmDeviceData data = (MiiHmDeviceData) message.data();

        IotDeviceVo iotDeviceVo = iotDeviceMapper.queryIotDeviceBySnAndAddr(sn, message.slaveAddress());
        if (iotDeviceVo == null) {
            return;
        }
        List<IotVariableVo> iotVariableVoList = iotDeviceMapper.variableList(iotDeviceVo.getTemplatesId());

        iotVariableVoList.sort(Comparator.comparingInt(IotVariable::getSerialNum));
        List<Integer> minDataFormatList = Arrays.asList(1, 2, 3);
        List<Integer> maxDataFormatList = Arrays.asList(4, 5);
        for (IotVariableVo iotVariableVo : iotVariableVoList) {
            String valueHex = "";
            try {
                if (maxDataFormatList.contains(iotVariableVo.getDataFormatValue())) {
                    valueHex = data.data().substring((iotVariableVo.getSerialNum() - 1) * 4, ((iotVariableVo.getSerialNum() - 1) * 4) + 8);
                } else {
                    valueHex = data.data().substring((iotVariableVo.getSerialNum() - 1) * 4, ((iotVariableVo.getSerialNum() - 1) * 4) + 4);
                }
                log.info("变量名称：" + iotVariableVo.getVariableName() + "，变量值：" + valueHex);
                String value;
                // 整数
                if (iotVariableVo.getNumberFormatValue() == 0) {
//                16位 无符号	1  16位 有符号	2  16位 BCD	3  32位浮点数	4  32位整数	5
                    if (valueHex.equals("00000000") || valueHex.equals("0000")) {
                        value = "0";
                    } else {
                        int valueInt = Integer.parseInt(trimTrailingZerosFromHex(valueHex), 16);
                        value = String.valueOf(valueInt);
                    }
                } else { // 小数
                    if (valueHex.equals("00000000") || valueHex.equals("0000")) {
                        value = "0.0";
                    } else {
                        float valueFloat = convertFloat(iotVariableVo.getNumberFormatValue(), valueHex);
                        value = String.valueOf(valueFloat);
                    }
                }
                IotVariableValue iotVariableValue = new IotVariableValue();
                iotVariableValue.setIotVariableId(iotVariableVo.getId());
                iotVariableValue.setIotDeviceId(iotDeviceVo.getId());
                iotVariableValue.setVariableValue(value);
                iotVariableValue.setCreateTime(new Date());
                iotVariableValue.setCreateBy("IotDataListener");
                iotVariableValue.setUpdateTime(new Date());
                iotVariableValue.setUpdateBy("IotDataListener");
                iotVariableValueMapper.insertIotVariableValue(iotVariableValue);

                // 保存临时表
                saveTempVariableValue(iotVariableValue);
            } catch (Exception e) {
                log.info("变量解析错误：变量名称：" + iotVariableVo.getVariableName() + "，变量值：" + valueHex);
            }
        }
    }

    private void saveTempVariableValue(IotVariableValue iotVariableValue){
        iotVariableValueTempMapper.deleteIotVariableValueTempByConditions(iotVariableValue);
        IotVariableValueTemp iotVariableValueTemp = new IotVariableValueTemp();
        iotVariableValueTemp.setVariableValue(iotVariableValue.getVariableValue());
        iotVariableValueTemp.setIotVariableId(iotVariableValue.getIotVariableId());
        iotVariableValueTemp.setIotDeviceId(iotVariableValue.getIotDeviceId());
        iotVariableValueTemp.setCreateTime(new Date());
        iotVariableValueTemp.setCreateBy("IotDataListener");
        iotVariableValueTemp.setUpdateTime(new Date());
        iotVariableValueTemp.setUpdateBy("IotDataListener");
        iotVariableValueTempMapper.insertIotVariableValueTemp(iotVariableValueTemp);
    }

    private void forwardOrder() {

    }

    public static void main1(String[] args) {
        //00ff0000   42738806  00000ac5
        int valueInt = Integer.parseInt(trimTrailingZerosFromHex("41b1"), 16);
        float valueFloat = new IotDataListener().convertFloat(1, "4437");

        System.out.println(valueInt);
        System.out.println(valueFloat);
//
//        System.out.println(trimTrailingZerosFromHex("00000000"));
//        System.out.println(new IotDataListener().convertFloat(2,"457a0000"));

//        String data = "0001000041550e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000041b5538e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
//        String valueHex = data.substring((26 - 1) * 4, ((26 - 1) * 4) + 8);
//        System.out.println(valueHex);
//        System.out.println(new IotDataListener().convertFloat(2, "41b5538e"));



    }

    private float convertFloat(int scale, String valueHex) {
        int intBits = Integer.parseInt(valueHex, 16);
        Float value = Float.intBitsToFloat(intBits);
        BigDecimal bd = BigDecimal.valueOf(value).setScale(scale, RoundingMode.HALF_UP);
        return bd.floatValue();
    }

    public static void main(String[] args) {
        float valueFloat = new IotDataListener().convertFloat(1, "00013eb3");
        System.out.println(valueFloat);

        int valueInt = Integer.parseInt(trimTrailingZerosFromHex("002b"), 16);
        String value = String.valueOf(valueInt);
        System.out.println(value);
    }

    public static String trimTrailingZerosFromHex(String hex) {
        return hex.replaceFirst("0+(?=0$|$)", "");
    }

}
